🧵Refactor receive responses thread sync#693
Closed
nevans wants to merge 8 commits into
Closed
Conversation
Collaborator
Author
|
It looks like some of this made tests that assert specific connection closing errors a bit flakier. On the one hand, it's not a big deal if client and receiver thread code, running simultaneously, sometimes results in |
db93f56 to
cddcbc9
Compare
I'm not sure why this was outside the `synchronize`...
There's no good reason to release the lock only to immediately reacquire it for exception handling. That might allow commands to be started (or continued) while still propagating irrelevant response errors. By moving the `rescue` clause inside the `synchronize` block, `begin` and `end` are now superfluous and can be removed. But that makes the diff seem much larger than it should, so I'm saving it for a later branch.
Although it wasn't obvious at first glance, because nearly every possible error is caught by a `rescue Exception` clause, this is effectively no different from what was already happening. This structure makes that much more obvious. Also, by moving this code into the `ensure`, it allows us to simplify error handling elsewhere, by simply raising or re-raising an exception. This also lets us move `state_logout!` inside the `synchronize` block.
By resetting `@exception` inside the synchronize block at the end of the loop, we don't need to release and immediately reacquire the lock each time through the loop.
The receiver thread now enters the logout state _before_ signaling the conditional variables for the last time. This is less surprising than doing it afterward, and it also makes some of the other `state_logout!` calls redundant.
With this change, an EOFError `@exception` may be assigned a receiver thread backtrace. Previously, it might've been raised in the client thread which, would set the backtrace for that client thread.
cddcbc9 to
cf63612
Compare
This delays setting `@exception` until it can be synchronized with everything else in the `ensure` block. NOTE: this could be simplified further: drop the `rescue` clause and use `$!` in the `ensure` clause. But that seems to trigger a TruffleRuby bug: truffleruby/truffleruby#4308
Since we're handling everything inside the ensure clause, we can drop the rescue clause and use `$!` in the ensure clause. But please note that this seems to trigger a TruffleRuby bug: truffleruby/truffleruby#4308
cf63612 to
3d5f3f3
Compare
Collaborator
Author
|
The last bit may make it into a future PR. But the bulk of the refactoring was done via #694. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related to #692, but that handles code that executes in client thread(s) and this handles code that executes in the receiver thread.
Notable changes:
synchronizeonce per loop, to handle the response.@exceptionat the start is moved to the end (unless connection_closed).state_logout!calls redundant.connection_stateis relatively new, and it is not expected that this difference should impact much code anyway.EOFErrormay be assigned a receiver thread backtrace, similarly to other exceptions that are raised by response reading or parsing. This will be significantly improved by 🧵🥅 Reraise receiver thread errors with caller's backtrace #691.@exceptionin the synchronize block inside the ensure clause. This makes the loop much simpler to understand, and now we don't release and immediately re-acquire the lock with (slightly) inconsistent state.@sock.closefor exceptions fromget_responseis no longer synchronized. This converts some instances ofIOError, "stream closed"intoIOError, "stream closed by another thread".This change was reverted. It made the tests flakier, and it's not too burdensome to keep it in a
synchronizedblock.